package punctuatedEquilibriumTest;

import static org.junit.Assert.*;

import org.junit.Test;

import punctuatedEquilibrium.FloatComparison;
import punctuatedEquilibrium.Phenotype;
import punctuatedEquilibrium.PhenotypeFactory;
import punctuatedEquilibrium.Trait;
import punctuatedEquilibrium.TraitFactory;

public class PhenotypeTest {

	private static final int	DEFAULT_ERROR_PARAMETER	= 1;
	private static final int	MAXIMUM_VARIATION		= 1;

	// TODO refactor tests
	@Test
	public void testChangeWithSmallVariability() {
		Phenotype phenotype = PhenotypeFactory.getStandardPhenotype();
		phenotype.changeWithSmallVariability();
		assertNotEquals(phenotype, PhenotypeFactory.getStandardPhenotype());
	}

	@Test
	public void testCreate() {
		Trait[] traitArray = TraitFactory.getArrayOfTraits();
		Phenotype phenotype = new Phenotype(traitArray);
		assertNotNull(phenotype);
	}

	@Test
	public void testDuplicateWithSmallVariability() {
		Phenotype phenotype = PhenotypeFactory.getStandardPhenotype();
		Phenotype duplicate = phenotype.duplicateApplyingSmallVariability();
		double[] expected = convertToPrimitiveArray(phenotype
				.getArrayOfVariables());
		double[] actual = convertToPrimitiveArray(duplicate
				.getArrayOfVariables());
		assertArrayEquals(expected, actual, MAXIMUM_VARIATION);
	}

	@Test
	public void testGetArrayOfVariables() {
		Phenotype phenotype = PhenotypeFactory.getStandardPhenotype();
		double[] expected = convertToPrimitiveArray(phenotype
				.getArrayOfVariables());
		double[] actual = convertToPrimitiveArray(TraitFactory
				.getArrayOfTraitValues());
		assertArrayEquals(
				expected,
				actual,
				FloatComparison
						.tolerableErrorDependingOnExpectedValue(DEFAULT_ERROR_PARAMETER));
	}

	@Test
	public void testIsEquivalent() {
		Phenotype phenotype = PhenotypeFactory.getStandardPhenotype();
		Phenotype equivalent = PhenotypeFactory.getStandardPhenotype();
		assertTrue(phenotype.isEquivalent(equivalent));

	}

	@Test
	public void testIsEquivalent2() {
		Trait[] emptyTraits = TraitFactory.getArrayOfTraits();
		Phenotype phenotype = new Phenotype(emptyTraits);
		Phenotype equivalent = new Phenotype(emptyTraits);
		assertTrue(phenotype.isEquivalent(equivalent));
	}

	@Test
	public void testIsNotEquivalent() {
		Phenotype phenotype = PhenotypeFactory.getStandardPhenotype();
		Phenotype equivalent = phenotype.duplicateApplyingSmallVariability();
		assertFalse(phenotype.isEquivalent(equivalent));

	}

	private double[] convertToPrimitiveArray(Double[] arrayOfVariables) {
		double[] arrayOfPrimitives = new double[arrayOfVariables.length];
		for (int i = 0; i < arrayOfPrimitives.length; i++) {
			arrayOfPrimitives[i] = arrayOfVariables[i];
		}
		return arrayOfPrimitives;
	}
}